-- Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
-- 
-- this file licensed under the Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
--
-- THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
-- PURPOSE.
-- See the Mulan PSL v2 for more details.

local class = require 'mc.class'
local log = require 'mc.logging'
local client = require 'thermal_mgmt.client'
local enums = require 'basic_cooling.define.cooling_enums'
local props = require 'basic_cooling.define.cooling_properties'
local base = require 'basic_cooling.data_keeping.base'
local singleton = require 'mc.singleton'
local utils = require 'basic_cooling.cooling_utils'
local energy_metric_data_keeping = require 'basic_cooling.data_keeping.energy_metric_data_keeping'
local c_fan_object = require 'fan_object'

local threshold_sensor_data_keeping = class(base)

function threshold_sensor_data_keeping:ctor(bus)
    self.obj_name = ""
    -- 监听的资源树路径
    self.paths_table = {
        "/bmc/kepler/Systems/:SystemId/ThresholdSensors/:Id"
    }
    self.threshold_sensor_interface = "bmc.kepler.Systems.ThresholdSensor"
    self.threshold_sensor_display_interface = "bmc.kepler.Systems.ThresholdSensorDisplay"
    -- 监听的接口
    self.interfaces_table = {
        [self.threshold_sensor_display_interface] = {
            [enums.data_keeping_config.FOREACH_FUNC] = client.ForeachThresholdSensorDisplayObjects,
            [enums.data_keeping_config.PROPERTIES] = {
                [props.THRESHOLD_SENSOR_DISPLY.HEALTH] = enums.data_keeping_log.NO_LOG
            }
        },
        [self.threshold_sensor_interface] = {
            [enums.data_keeping_config.FOREACH_FUNC] = client.ForeachThresholdSensorObjects,
            [enums.data_keeping_config.PROPERTIES] = {
                [props.THRESHOLD_SENSOR_DISPLY.SENSOR_NAME] = enums.data_keeping_log.NO_LOG,
                [props.THRESHOLD_SENSOR_DISPLY.SENSOR_IDENTIFIER] = enums.data_keeping_log.NO_LOG
            }
        }
    }
end

function threshold_sensor_data_keeping:init()
    self.super.init(self)
    self.c_fan_object = c_fan_object
    self.utils = utils
    self.props = props
end

function threshold_sensor_data_keeping:action_after_obj_added(path, interface)
    if self.objs[path][interface][self.props.THRESHOLD_SENSOR_DISPLY.SENSOR_NAME] == self.props.INLET_TEMP or
        self.objs[path][interface][self.props.THRESHOLD_SENSOR_DISPLY.SENSOR_IDENTIFIER] == self.props.INLET_TEMP then
        self.inlet_path = path
    end
    if self.objs[path][interface][self.props.THRESHOLD_SENSOR_DISPLY.SENSOR_NAME] == self.props.OUTLET_TEMP or
        self.objs[path][interface][self.props.THRESHOLD_SENSOR_DISPLY.SENSOR_IDENTIFIER] == self.props.OUTLET_TEMP then
        self.outlet_path = path
    end
end

function threshold_sensor_data_keeping:action_after_property_changed(path, interface, prop, value)
    if value == "OK" then
        return
    end
    local sensor_name =
        self.objs[path][self.threshold_sensor_interface].obj[props.THRESHOLD_SENSOR_DISPLY.SENSOR_NAME]
    local temp_value = self.objs[path][interface].obj[props.THRESHOLD_SENSOR_DISPLY.READING_DISPLEY]
    local inlet_temp, outlet_temp = nil, nil
    if self.inlet_path then
        inlet_temp = self.objs[self.inlet_path][self.threshold_sensor_display_interface].obj[
            props.THRESHOLD_SENSOR_DISPLY.READING_DISPLEY]
    end
    if self.outlet_path then
        outlet_temp = self.objs[self.outlet_path][self.threshold_sensor_display_interface].obj[
            props.THRESHOLD_SENSOR_DISPLY.READING_DISPLEY]
    end
    local log_msg =
        string.format('SensorName[%s] Health change to %s, value:%s, Inlet Temp:%s, Output Temp:%s, ',
        sensor_name, value, temp_value, inlet_temp, outlet_temp)
    if not self.energy_metric_data_keeping then
        self.energy_metric_data_keeping = energy_metric_data_keeping.get_instance()
    end
    local system_power = self.energy_metric_data_keeping:get_system_power()
    local fan_total_power = self.energy_metric_data_keeping:get_fan_total_power()
    log_msg = log_msg .. string.format('System power:%s, Fan total power:%s,', system_power, fan_total_power)
    local fan_data_format = ' [fanId:%s|PWM:%s|Speed:%s]'
    local pwm, speed = nil, nil
    self.c_fan_object.collection:fold(function (_, fan_obj)
        pwm, speed = nil, nil
        if fan_obj.MaxSupportedPWM and fan_obj.MaxSupportedPWM ~= 0 then
            pwm = math.floor((fan_obj.HardwarePWM / fan_obj.MaxSupportedPWM) * 100)
        end
        if fan_obj.IsTwins then
            speed = fan_obj.Coefficient * fan_obj.FrontSpeed .. '/' .. fan_obj.Coefficient * fan_obj.RearSpeed
        else
            speed = fan_obj.Coefficient * fan_obj.RearSpeed
        end
        log_msg = log_msg .. string.format(fan_data_format, fan_obj.FanId, pwm, speed)
    end)
    self.utils.thermal_log(log_msg)
end

return singleton(threshold_sensor_data_keeping)